package com.youi.webapp;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.youi.entity.*;
import com.youi.service.*;
import com.youi.util.LogUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.youi.common.Common;
import com.youi.common.DelStatus;
import com.youi.exception.BusinessException;
import com.youi.manage.HttpRequestManage;
import com.youi.model.GoodsStatistics;
import com.youi.util.CommonInfoUtil;
import com.youi.util.DateUtil;
import com.youi.util.JsonUtil;

@Controller
public class OtherScriptController  extends HttpRequestManage{
	
	@Autowired
	private GoodsService goodsService;
	@Autowired
	private OrdergoodsService ordergoodsService;
	@Autowired
	private UserorderService userorderService;
	@Autowired
	private GoodssizeService goodssizeService;
	@Autowired
	private OrderprofitdetailService orderprofitdetailService;
	@Autowired
	private UserwechatService userwechatService;
	@Autowired
	private SetleaderlevelService setleaderlevelService;
	@Autowired
	private LeaderfanService leaderfanService;
	@Autowired
	private GroupleaderService groupleaderService;
	@Autowired
	private LeaderstoreService leaderstoreService;
	@Autowired
	private UserService userService;
	@Autowired
	private MerchantService merchantService;
	@Autowired
	private LeaderprofitdetailService leaderprofitdetailService;
	@Autowired
	private LeaderprofitService leaderprofitService;
	
	



	////////////////////////////////////////////////////////////////////////////////
	// 以下是重新设置佣金数据

	//千分之三，也就是0.3%
	static private double SERVICE_RATE = 0.003;
	//商家分佣85%
	static private double STORE_RATE = 85;
	//一级分佣
	static private double LEVEL_1_RATE = 3;
	//二级分佣
	static private double LEVEL_2_RATE = 7;

	//帮助方法，用一个键值对获取参数
	static private Map<String,Object> mapWithOneEntry(String key,Object value){
		HashMap<String,Object> params=new HashMap<>();
		params.put(key,value);
		return params;
	}
	//帮助方法，用键值队获取参数，增加delstatus == 0条件
	static private Map<String,Object> mapWithOneEntryNoDel(String key,Object value){
		Map<String,Object> params = mapWithOneEntry(key,value);
		params.put(Common.DELSTATUS,DelStatus.NODEL);
		return params;
	}

	//帮助方法，四舍六入五留双
	//以后应该从entity开始直接支持BigDecimal
	static private double ROUND_HALF_EVEN(double value){
		BigDecimal result = new BigDecimal(value).setScale(2, BigDecimal.ROUND_HALF_EVEN);
		return result.doubleValue();
	}

	/**
	 * 重置佣金信息
	 */
	@ResponseBody
	@RequestMapping("patchOrderprofitdetail")
	public  String  patchOrderprofitdetail(ModelMap modelMap,HttpServletRequest request) throws BusinessException, IOException, ParseException {
		LogUtil.Info("patchOrderprofitdetail");
		/**
		 * 	查询脚本：
		 * 		select a.orderNo, a.gmtCreated, a.userid, a.amount, a.status, a.leaderid, b.phone, b.authStoreCode, b.gmtReg
		 * 		from userorder a
		 * 			left join leaderstore b on a.leaderid = b.leaderid
		 * 		where not exists(select 1 from orderprofitdetail b where a.orderNo = b.orderNo)
		 * 		and a.status not in(-1,0)
		 * 		and a.gmtCreated > '2020-01-01'
		 * 		order by a.gmtCreated;
		 *
		 * 	数据说明：
		 * 		这部分数据是已付款订单中，没有在订单分佣明细表产生记录。
		 */
//		Map<String,Object> prams = new HashMap<String,Object>();
//		prams.put(Common.DELSTATUS,DelStatus.NODEL);
//		prams.put(Common.STATUS, Arrays.asList(1,2,3,4,5));
//		List<Userorder> targetList = userorderService.getByParams(prams);
		List<Userorder> targetList = userorderService.getByNoOrderprofitdetail();
		for (Userorder userorder : targetList){

			LogUtil.Info("start process: "+userorder.getId());

			//数据准备
			Double payAmount = userorder.getPayableAmount();
			//商家佣金，TODO: 也可以直接从商家获取
			Double merchantComms=ROUND_HALF_EVEN(payAmount*(STORE_RATE*0.01));
			//手续费
			Double serviceCharge=ROUND_HALF_EVEN(payAmount*SERVICE_RATE);
			Double platComms=null;

			//用于保存的orderprofitdetail记录
			Map<String,Object> prams = new HashMap<String,Object>();
			prams.put(Common.DELSTATUS,DelStatus.NODEL);
			prams.put("orderNo", userorder.getOrderNo());
			Orderprofitdetail orderprofitdetail=orderprofitdetailService.getByParam(prams);
			if (orderprofitdetail==null) {
				 orderprofitdetail=new Orderprofitdetail(null, userorder.getOrderNo(), userorder.getPayableAmount());
			
			}
			/**
			 * 	2、	完善用户订单表userorder的leaderid，原因是部分佳选官下单后订单表没有设置leaderid，这对后面订单分佣明细表修复产生影响；
			 * 		a. 查询leaderid为空的订单，获取订单的userid、下单时间
			 */
			Groupleader groupleader = null;

			if (userorder.getLeaderId() == null){
				//a. 查询leaderid为空的订单，获取订单的userid、下单时间
				User user=userService.get(userorder.getUserId()); //原来写为 .getId()
				if (user==null){
					LogUtil.Info("fail fetch user:"+userorder.getUserId());
					continue;
				}
				//b. 确认userid对应的用户是否已经注册为佳选官，获取其注册时间
				//只要这个人之前出现在groupLeader表，那他当时就是团长
				groupleader = groupleaderService.getByParamss(
						mapWithOneEntry(Common.USERID ,user.getId() ),
						null,null,null,null
				);

				//c. 如果是佳选官用户订单，比较订单下单时间和佳选官注册时间
				if (groupleader != null ){
					if (userorder.getGmtOrder().before( groupleader.getGmtCreated ()) ) {
						//下单时间 < 注册时间， 订单leaderid不变，保持空值；
						userorder.setLeaderId(null);
						groupleader = null;
					}else{
						//下单时间 ≥ 注册时间，订单leaderid设置为该用户的佳选官ID；
						userorder.setLeaderId(groupleader.getId()) ;
					}
				}
			}else{ //从userorder.getLeaderId()获取leader
				groupleader = groupleaderService.getByParamss(
						mapWithOneEntry(Common.ID  ,userorder.getLeaderId() ),
						null,null,null,null
				);
				if (groupleader == null) {
					LogUtil.Info("fail fetch groupleader:"+userorder.getLeaderId ());
					continue;
				}
			}

			//userorder.leaderId和groupleader要么同时为空，要么同时存在
			if (userorder.getLeaderId() == null) {
				/**
				 * 		a. 订单leaderid为空值，则作为白户普通订单处理，分佣情况：
				 * 			顶级佳选官：无分佣
				 * 			二级佳选官：无分佣
				 * 			普通分佣：14.7%
				 * 			商户分佣：85%
				 * 			服务费：0.3%
				 */
				//当用户为非粉丝和非团长时，而且不通过链接购买
				platComms=payAmount-merchantComms-serviceCharge;//平台佣金 认为payAmount已经是小数点后只有两位的标准格式了，所以不做四舍六入
				orderprofitdetail.setType(2); //订单类型(0顶级团长分佣 1二级团长分佣 2平台分佣) ,原来为0，这里改成2
				orderprofitdetail.setPlatAmount(platComms);
				orderprofitdetail.setMerchantId(userorder.getMerchantId());
				orderprofitdetail.setMerAmount(merchantComms);
				orderprofitdetail.setServiceCharge(serviceCharge);
				orderprofitdetail.setGmtModify(new Date());
				orderprofitdetailService.saveOrUpdate(orderprofitdetail);
				LogUtil.Info("type == 0 save");
				continue;
			}

			/**
			 * 		b. 订单leaderid有值，需区分对应佳选官等级，按佳选官等级分佣情况：
			 * 			i. leaderid对应佳选官为顶级佳选官
			 * 				顶级佳选官：10%
			 * 				二级佳选官：无分佣
			 * 				普通分佣：4.7%
			 * 				商户分佣：85%
			 * 				服务费：0.3%
			 */

			//因为groupLeader记录里没有一级和二级的信息，这方面的数据要从storeLeader获取
			//用leaderId获取leaderStore信息，店铺注册时间应该小于订单创建时间
			List<Leaderstore> storeList = leaderstoreService.getByParamsList(
					mapWithOneEntry("leaderId", groupleader.getId()),
					null,
					mapWithOneEntry(Common.ID,Common.DESC),
					0,9999,null,
					mapWithOneEntry("gmtReg",userorder.getGmtCreated())
			);
			//取第一个（最新的那个），或者取level=1的那一个（顶级团长）
			Leaderstore leaderstore = null;
			for(Leaderstore lf : storeList) {
				if (lf.getLevel() == 1){
					leaderstore = lf;
					break;
				}else if (leaderstore == null){
					leaderstore = lf;
				}
			}
			if (leaderstore == null){
				LogUtil.Info("fail fetch leaderstore:" + groupleader.getId());
				continue;
			}
			if (leaderstore.getLevel()==1) { //团长等级(0普通用户 1顶级团长 2二级团长)
				LogUtil.Info("leaderstore.getLevel()==1");
				//订单为一级团长订单时
				//计算团长佣金
				//1.确定团长佣金比例
				double topLeaderRate= LEVEL_1_RATE + LEVEL_2_RATE;
				//2.计算团长佣金
				double leaderComms= ROUND_HALF_EVEN(payAmount*(topLeaderRate*0.01));
				//3.计算平台佣金
				platComms=payAmount-merchantComms-leaderComms-serviceCharge; //应该不需要四舍六入
				//添加分佣记录
				orderprofitdetail.setType(0); //(0顶级团长分佣 1二级团长分佣 2平台分佣)

				orderprofitdetail.setLeaderId1(leaderstore.getLeaderId());
				orderprofitdetail.setFirstUser(groupleader.getName());
				orderprofitdetail.setFirstAmount(leaderComms);

				orderprofitdetail.setPlatAmount(platComms);
				orderprofitdetail.setMerchantId(userorder.getMerchantId());
				orderprofitdetail.setMerAmount(merchantComms);
				orderprofitdetail.setServiceCharge(serviceCharge);
				orderprofitdetail.setGmtModify(new Date());
				orderprofitdetailService.saveOrUpdate(orderprofitdetail);
				LogUtil.Info("leaderstore.getLevel()==1 save");
			}else if(leaderstore.getLevel()==2){
				LogUtil.Info("leaderstore.getLevel()==2");
				//当团长为二级团长时
				//1.确定二级团长的佣金
				double secondLeaderComms=ROUND_HALF_EVEN(payAmount*(LEVEL_2_RATE*0.01));
				//2.确定一级团长佣金
				double firstLeaderComms=ROUND_HALF_EVEN(payAmount*(LEVEL_1_RATE*0.01));
				//3.计算一二级团长佣金的总和
				double allLeaderComms=secondLeaderComms+firstLeaderComms;
				//4.计算平台佣金
				platComms=payAmount-merchantComms-allLeaderComms-serviceCharge;

				//6.添加一级团长佣金信息
				//用storeId获取店铺的一级团长leaderStore信息
				//取最接近当时时间点的一级团长(部分store有多个一级团长）
				HashMap <String,Object> params=new HashMap<>();
				params.put("storeId", leaderstore.getStoreId());
				params.put("level", 1);
				Leaderstore topLeaderstore=leaderstoreService.getByParamss(
						params,
						null,
						mapWithOneEntry("gmtReg",Common.DESC),
						null,
						mapWithOneEntry("gmtReg",userorder.getGmtCreated())
				);
				if (topLeaderstore == null){
					LogUtil.Info("fail fetch topLeaderstore:" + leaderstore.getStoreId());
					continue;
				}

				//获取一级团长的groupLeader信息
				Groupleader firstGroupleader=groupleaderService.getByParam(
						mapWithOneEntry(Common.ID,topLeaderstore.getLeaderId()));
				if (firstGroupleader==null) {
					LogUtil.Info("fail fetch firstGroupleader:" + leaderstore.getLeaderId());
					continue;
				}
				//添加分佣记录
				orderprofitdetail.setType(1); //(0顶级团长分佣 1二级团长分佣 2平台分佣) 原为type，修改为1

				orderprofitdetail.setLeaderId1(topLeaderstore.getLeaderId());
				orderprofitdetail.setFirstUser(firstGroupleader.getName());
				orderprofitdetail.setFirstAmount(firstLeaderComms);

				orderprofitdetail.setLeaderId2(leaderstore.getLeaderId());
				orderprofitdetail.setSecondUser(groupleader.getName());
				orderprofitdetail.setSecondAmount(secondLeaderComms);

				orderprofitdetail.setPlatAmount(platComms);
				orderprofitdetail.setMerchantId(userorder.getMerchantId());
				orderprofitdetail.setMerAmount(merchantComms);
				orderprofitdetail.setServiceCharge(serviceCharge);

				orderprofitdetail.setGmtModify(new Date());
				orderprofitdetailService.saveOrUpdate(orderprofitdetail);
				LogUtil.Info("leaderstore.getLevel()==2 save");
			}else{
				LogUtil.Info("fail leaderstore's level: " +leaderstore.getLevel() +"("+ leaderstore.getId() + ")" );
			}			
		}
		return JsonUtil.toJson(CommonInfoUtil.SUCCESS,"操作成功");
	}


	/**
	 * 重置Leader佣金信息
	 */
	@ResponseBody
	@RequestMapping("patchLeaderprofitdetail")
	public  String  patchLeaderprofitdetail(ModelMap modelMap,HttpServletRequest request) throws BusinessException, IOException, ParseException {
		LogUtil.Info("patchLeaderprofitdetail");
//		String orderNo=getString("orderNo", request);
		/**
		 * 	查询脚本：
		 * 		select a.orderNo, a.gmtCreated, a.userid, a.amount, a.status, a.leaderid, b.phone, b.authStoreCode, b.gmtReg
		 * 		from userorder a
		 * 			left join leaderstore b on a.leaderid = b.leaderid
		 * 		where not exists(select 1 from leaderprofitdetail b where a.orderNo = b.orderNo)
		 * 		and a.status not in(-1,0)
		 * 		and a.gmtCreated > '2020-01-01'
		 * 		and a.leaderid is not null
		 * 		order by a.gmtCreated;
		 *
		 * 	数据说明：
		 * 		这部分数据是订单有leaderid值，但是没有生成该订单的佳选官分佣明细数据。
		 */
		List<Userorder> targetList = userorderService.getByNoLeaderprofitdetail();
//		Map<String,Object> prams = new HashMap<String,Object>();
//		prams.put(Common.DELSTATUS,DelStatus.NODEL);
//		prams.put("orderNo",orderNo);
//		List<Userorder> targetList = userorderService.getByParams(prams);
		for (Userorder userorder : targetList) {

			LogUtil.Info("start process: " + userorder.getId());

			Groupleader groupleader = groupleaderService.getByParamss(
					mapWithOneEntry(Common.ID  ,userorder.getLeaderId() ),
					null,null,null,null
			);
			if (groupleader == null) {
				LogUtil.Info("fail fetch groupleader:"+userorder.getLeaderId ());
				continue;
			}

			//因为groupLeader记录里没有一级和二级的信息，这方面的数据要从storeLeader获取
			//用leaderId获取leaderStore信息，店铺注册时间应该小于订单创建时间
			List<Leaderstore> storeList = leaderstoreService.getByParamsList(
					mapWithOneEntry("leaderId", groupleader.getId()),
					null,
					mapWithOneEntry(Common.ID,Common.DESC),
					0,9999,null,
					mapWithOneEntry("gmtReg",userorder.getGmtCreated())
			);
			//取第一个（最新的那个），或者取level=1的那一个（顶级团长）
			Leaderstore leaderstore = null;
			for(Leaderstore lf : storeList) {
				if (lf.getLevel() == 1){
					leaderstore = lf;
					break;
				}else if (leaderstore == null){
					leaderstore = lf;
				}
			}
			if (leaderstore == null){
				LogUtil.Info("fail fetch leaderstore:" + groupleader.getId());
				continue;
			}

			//数据准备
			Double payAmount = userorder.getPayableAmount();

			if (leaderstore.getLevel()==1) { //团长等级(0普通用户 1顶级团长 2二级团长)
				LogUtil.Info("leaderstore.getLevel()==1");
				//		a. 佳选官为顶级佳选官，生成一条分佣明细记录，记录该佳选官leaderid，对应分佣金额为订单金额的10%；
				double amount = ROUND_HALF_EVEN(payAmount*(LEVEL_1_RATE+LEVEL_2_RATE)*0.01);

				//private Integer type;					    //变更类型(0佣金订单收入 1提现支出 2退款支出)
				
				Leaderprofitdetail lpd = new Leaderprofitdetail(groupleader.getId(),0,amount,"佣金收入",userorder.getOrderNo());
				leaderprofitdetailService.saveOrUpdate(lpd);

				Map<String, Object> prms=new HashMap<String, Object>();
				prms.put(Common.DELSTATUS, DelStatus.NODEL);
				prms.put("leaderId", groupleader.getId());
				Leaderprofit leaderprofit =leaderprofitService.getByParam(prms);
				if (leaderprofit==null) {
					leaderprofit = new Leaderprofit(lpd.getLeaderId());
				}
				leaderprofit.setTotalAmount(leaderprofit.getTotalAmount()+amount);
				leaderprofit.setFrozen(leaderprofit.getFrozen()+amount);
				//TODO: withdres / frozen / balance / companyCode 都没有填。
				leaderprofitService.saveOrUpdate(leaderprofit);

			}else if(leaderstore.getLevel()==2){
				LogUtil.Info("leaderstore.getLevel()==2");
				//		b. 佳选官为二级佳选官，生成两条分佣明细记录，一条记录认证门店顶级佳选官leaderid，对应分佣3%；一条记录二级佳选官leaderid，对应分佣7%；

				//用storeId获取店铺的一级团长leaderStore信息
				//取最接近当时时间点的一级团长(部分store有多个一级团长）
				HashMap <String,Object> params=new HashMap<>();
				params.put("storeId", leaderstore.getStoreId());
				params.put("level", 1);
				Leaderstore topLeaderstore=leaderstoreService.getByParamss(
						params,
						null,
						mapWithOneEntry("gmtReg",Common.DESC),
						null,
						mapWithOneEntry("gmtReg",userorder.getGmtCreated())
				);
				if (topLeaderstore == null){
					LogUtil.Info("fail fetch topLeaderstore:" + leaderstore.getStoreId());
					continue;
				}

				//获取一级团长的groupLeader信息
				Groupleader firstGroupleader=groupleaderService.getByParam(
						mapWithOneEntry(Common.ID,topLeaderstore.getLeaderId()));
				if (firstGroupleader==null) {
					LogUtil.Info("fail fetch firstGroupleader:" + leaderstore.getLeaderId());
					continue;
				}

				double amountLevel2 = ROUND_HALF_EVEN(payAmount*LEVEL_2_RATE*0.01);

				//private Integer type;					    //变更类型(0佣金订单收入 1提现支出 2退款支出)
				Leaderprofitdetail lpd2 = new Leaderprofitdetail(groupleader.getId(),0, amountLevel2,"佣金收入",userorder.getOrderNo());

				double amountLevel1 = ROUND_HALF_EVEN(payAmount*LEVEL_1_RATE*0.01);
				Leaderprofitdetail lpd1 = new Leaderprofitdetail(firstGroupleader.getId(),0, amountLevel1,"佣金收入",userorder.getOrderNo());


				leaderprofitdetailService.saveOrUpdate(lpd2);
				leaderprofitdetailService.saveOrUpdate(lpd1);

				Map<String, Object> prms=new HashMap<String, Object>();
				prms.put(Common.DELSTATUS, DelStatus.NODEL);
				prms.put("leaderId", lpd2.getLeaderId());
				Leaderprofit lp2=leaderprofitService.getByParam(prms);
				if (lp2==null) {
					lp2 = new Leaderprofit(lpd2.getLeaderId());
				}
				lp2.setTotalAmount(lp2.getTotalAmount()+amountLevel2);
				lp2.setFrozen(lp2.getFrozen()+amountLevel2);
				//TODO: withdres / frozen / balance / companyCode 都没有填。
				leaderprofitService.saveOrUpdate(lp2);

				prms=new HashMap<String, Object>();
				prms.put(Common.DELSTATUS, DelStatus.NODEL);
				prms.put("leaderId", lpd1.getLeaderId());
				Leaderprofit lp1=leaderprofitService.getByParam(prms);
				if (lp1==null) {
					lp1 = new Leaderprofit(lpd1.getLeaderId());
				}
				lp1.setTotalAmount(lp2.getTotalAmount()+amountLevel1);
				lp1.setFrozen(lp2.getFrozen()+amountLevel1);
				//TODO: withdres / frozen / balance / companyCode 都没有填。
				leaderprofitService.saveOrUpdate(lp1);

			}else{
				LogUtil.Info("fail leaderstore's level: " +leaderstore.getLevel() +"("+ leaderstore.getId() + ")" );
			}
		}
		return JsonUtil.toJson(CommonInfoUtil.SUCCESS,"操作成功");
	}
	
	//获取用户身份过程中取到的数据结构
		private static class UserIdentity{
			final int type; //0非粉丝 1粉丝 2团长
			final Groupleader groupleader;
			final Leaderfan leaderfan;
			private UserIdentity(int type, Groupleader groupleader, Leaderfan leaderfan) {
				this.type = type;
				this.groupleader = groupleader;
				this.leaderfan = leaderfan;
			}
		}
		
		/**
		 * 检测订单用户身份
		 * @param userorder
		 * @return
		 */
		private UserIdentity checkUserIdentity(Userorder userorder) {
			//订单发生时间，必须判断用户在订单发生之前已经具备某身份
			Date beforeDate = userorder.getGmtCreated();
			Long userId = userorder.getUserId();
			//首先从groupleader获取
			//只要这个人之前出现在groupLeader表，那他当时就是团长
			Groupleader groupleader = groupleaderService.getByParamss(
					mapWithOneEntry(Common.USERID ,userId),
					null,null,null,
					mapWithOneEntry(Common.GMTCREATED ,beforeDate)
			);
			if (groupleader != null ){
				return new UserIdentity(2,groupleader,null);
			}
			//从userorder里的unioid判断他是否是粉丝
			Leaderfan leaderfan = leaderfanService.getByParamss(
					mapWithOneEntry("unionid",userorder.getUnioid()),
					null,null,null,
					mapWithOneEntry(Common.GMTCREATED,beforeDate)
			);
			if (leaderfan == null){ //可能不必要？
				Userwechat userwechat = userwechatService.getByParam(mapWithOneEntryNoDel(Common.USERID,userId));
				if (userwechat!=null){
					leaderfan = leaderfanService.getByParamss(
							mapWithOneEntry("unionid",userwechat.getUnionid()),
							null,null,null,
							mapWithOneEntry(Common.GMTCREATED,beforeDate)
					);
				}
			}
			if (leaderfan != null ){
				return new UserIdentity(1,null,leaderfan);
			}
			return new UserIdentity(0,null,null);
		}


	/**
	 * 处理订单的空leaderID问题
	 */
	@ResponseBody
	@RequestMapping("patchNullLeader")
	public  String  patchNullLeader(ModelMap modelMap,HttpServletRequest request) throws BusinessException, IOException, ParseException {
//		//获取所有订单（取消注释则是按orderNo获取）
		List<Userorder> userorderList=userorderService.getByNoLeaderID();
		if (userorderList==null&&userorderList.size()>0) {
			return JsonUtil.toJson(CommonInfoUtil.NULLDATA,"空数据");
		}
		int notFanNotLeaderCount = 0;
		//对于每一条订单
		for (Userorder userorder : userorderList) {
			LogUtil.Info("process: " + userorder.getId());
			//获取订单发生时，下单人的身份
			UserIdentity userIdentity = checkUserIdentity(userorder);
			//0非粉丝 1粉丝 2团长
			switch(userIdentity.type){
				case 0:
					notFanNotLeaderCount+=1;
					LogUtil.Info("current user is neither fan nor leader: " + userorder.getUserId() );
					continue;
				case 1:
					//是粉丝
					Long leaderId = userIdentity.leaderfan.getLeaderId();
					userorder.setLeaderId(leaderId);
					userorderService.saveOrUpdate(userorder);
					break;
				case 2:
					//是团长
					leaderId = userIdentity.groupleader.getId();
					userorder.setLeaderId(leaderId);
					userorderService.saveOrUpdate(userorder);
					break;
				default:
					LogUtil.Info("fail: current user 's type is not valid: " + userorder.getUserId() + "(" + userIdentity.type);
			}
		}
		if (notFanNotLeaderCount >0) {
			LogUtil.Info("fail :"+notFanNotLeaderCount+" users is neither fan nor leader");
		}
		return JsonUtil.toJson(CommonInfoUtil.SUCCESS,"操作成功");
	}

	
	/**
	 * 处理订单的空leaderID问题
	 */
	@ResponseBody
	@RequestMapping("patchLeaderprofit")
	public  String  patchLeaderprofit(ModelMap modelMap,HttpServletRequest request) throws BusinessException, IOException, ParseException {
		List<Map> allData = userorderService.getLeaderprofitdetailStatByLeaderId();
		for( Map one : allData){
			Long leaderid = (Long)one.get("leaderid");
			BigDecimal sumAmount = (BigDecimal)one.get("sumAmount");
//			LogUtil.Info(leaderid.getClass()+"+"+sumAmount.getClass());
			if((leaderid==null)||(sumAmount==null)) {
				LogUtil.Info("fail :not valid data:"+leaderid+"-"+sumAmount);
			}
			HashMap params=new HashMap<String, Object>();
			params.put(Common.DELSTATUS, DelStatus.NODEL);
			params.put("leaderId",leaderid);
			HashMap sortParams = new HashMap<String,Object>();
			//优先取非删除项的较早一条，如果执行过之前的脚本，可以避免把余额更新到后来不适当新增的记录上。
			sortParams.put(Common.GMTCREATED, Common.ASC);
			Leaderprofit leaderprofit = leaderprofitService.getByParamss(params, null, sortParams, null, null);
			if (leaderprofit==null){
				//新建一个
				leaderprofit = new Leaderprofit(leaderid);
				leaderprofit.setGmtCreated(new Date());
				leaderprofit.setDelStatus(DelStatus.NODEL);
				leaderprofit.setGmtModify(leaderprofit.getGmtCreated());
			}else{
				//数值正确则不进行更新
				if (leaderprofit.getTotalAmount() == sumAmount.doubleValue()){
					continue;
				}
			}
			leaderprofit.setTotalAmount(sumAmount.doubleValue());
			leaderprofitService.saveOrUpdate(leaderprofit);
		}
		return JsonUtil.toJson(CommonInfoUtil.SUCCESS,"操作成功");
	}

//	/**
//	 * 重置佣金数据
//	 * @param modelMap
//	 * @param request
//	 * @return
//	 * @throws BusinessException
//	 * @throws IOException
//	 * @throws ParseException
//	 */
//	@ResponseBody
//	@RequestMapping("resetorderprofitdata")
//	public  String  resetorderprofitdata(ModelMap modelMap,HttpServletRequest request) throws BusinessException, IOException, ParseException {
////		String orderNo=getString("orderNo", request);
//		Map<String, Object> prams=new HashMap<String, Object>();
//		prams.put(Common.DELSTATUS, DelStatus.NODEL);
//		prams.put(Common.STATUS, Arrays.asList(1,2,3,4,5));
////		prams.put("orderNo", orderNo);
//		//获取所有订单（取消注释则是按orderNo获取）
//		List<Userorder> userorderList=userorderService.getByParams(prams);
//		if (userorderList==null&&userorderList.size()>0) {
//			return JsonUtil.toJson(CommonInfoUtil.NULLDATA,"空数据");
//		}
//		for (Userorder userorder : userorderList) {
//
////			//为了调错，这四条记录是出错记录
////			Long uoid = userorder.getId();
////			if ((uoid!=78)&&(uoid!=1726)&&(uoid!=2416)&&(uoid!=2547)) {
////				continue;
////			}
//
//			prams=new HashMap<String, Object>();
//			prams.put(Common.DELSTATUS, DelStatus.NODEL);
//			prams.put("orderNo", userorder.getOrderNo());
//			//对每张订单获取分利记录
//			Orderprofitdetail orderprofitdetail=orderprofitdetailService.getByParam(prams);
//			//如果没有分利记录则新建一个
//			if (orderprofitdetail==null) {
//				orderprofitdetail=new Orderprofitdetail(null, userorder.getOrderNo(), userorder.getPayableAmount());
//				orderprofitdetail.setGmtCreated(new Date());
//				orderprofitdetail.setDelStatus(DelStatus.NODEL);
//			}else{
//				//如果接下来整个数据全部要重新覆盖，那么先把所有的值设置成null
//				orderprofitdetail.setType(null);
//				orderprofitdetail.setCommission(null);
//				orderprofitdetail.setLeaderId1(null);
//				orderprofitdetail.setFirstUser(null);
//				orderprofitdetail.setFirstAmount(null);
//				orderprofitdetail.setLeaderId2(null);
//				orderprofitdetail.setSecondUser(null);
//				orderprofitdetail.setSecondAmount(null);
//				orderprofitdetail.setPlatAmount(null);
//				orderprofitdetail.setMerchantId(null);
//				orderprofitdetail.setMerAmount(null);
//				orderprofitdetail.setServiceCharge(null);
//			}
//			//获取当前订单的用户对象
//			User user=userService.get(userorder.getUserId()); //原来写为 .getId()
//			if (user==null){
//				LogUtil.Info("fail fetch user:"+userorder.getUserId());
//				continue;
//			}
//
//			//用当前订单的店铺ID获取店铺
//			Merchant merchant=merchantService.get(userorder.getMerchantId());
//			if (merchant==null){
//				LogUtil.Info("fail fetch merchant:"+userorder.getMerchantId());
//				continue;
//			}
//
//			//计算分利逻辑
//			getLeaderprofit(userorder, userorder.getPayableAmount(), user, merchant, orderprofitdetail);
//		}
//		return JsonUtil.toJson(CommonInfoUtil.SUCCESS,"操作成功");
//	}
//
//
//
//	/**
//	 * 团长佣金信息分账
//	 */
//	public void getLeaderprofit(Userorder userorder,Double payAmount,User user,Merchant merchant,Orderprofitdetail orderprofitdetail) {
//		LogUtil.Info("getLeaderprofit:"+userorder.getId());
////		DecimalFormat amount=new DecimalFormat("0.00");
//		//商家佣金，猜测这里是85%
//		Double merchantComms=ROUND_HALF_EVEN(payAmount*(1-(merchant.getCommissionRatio()*0.01)));
//		//手续费，0.03%应该是 0.0003，原为0.003
//		Double serviceCharge=ROUND_HALF_EVEN(payAmount*SERVICE_RATE);
//		Double platComms=null;
//		//判断用户身份，0非粉丝 1粉丝 2团长
//		UserIdentity identity=checkUserIdentity(userorder); //获取订单创建时点用户的身份
//		LogUtil.Info("identity:"+identity.type);
//		if ((identity.type==0)&&(userorder.getLeaderId()==null)) {
//			//当用户为非粉丝和非团长时，而且不通过链接购买
//			platComms=payAmount-merchantComms-serviceCharge;//平台佣金 认为payAmount已经是小数点后只有两位的标准格式了，所以不做四舍六入
//			orderprofitdetail.setType(2); //订单类型(0顶级团长分佣 1二级团长分佣 2平台分佣) ,原来为0，这里改成2
//			orderprofitdetail.setPlatAmount(platComms);
//			orderprofitdetail.setMerchantId(userorder.getMerchantId());
//			orderprofitdetail.setMerAmount(merchantComms);
//			orderprofitdetail.setServiceCharge(serviceCharge);
//			orderprofitdetail.setGmtModify(new Date());
//			int updateCount = orderprofitdetailService.saveOrUpdate(orderprofitdetail);
//			System.out.println("updateCount"+updateCount);
//			LogUtil.Info("type == 0 save");
//		}else if ((identity.type==1)||((identity.type==0)&&(userorder.getLeaderId()!=null))) {
//			//当用户为粉丝的时候，或者通过链接购买的时候
//			getleaderComms(identity, orderprofitdetail, userorder, payAmount, merchantComms, serviceCharge);
//		}else if (identity.type==2) {
//			//当用户为团长的时候
////			getLeaderOneselfComms(amount, identity, orderprofitdetail, userorder, payAmount, merchantComms, serviceCharge, platComms,1);
//			getleaderComms(identity, orderprofitdetail, userorder, payAmount, merchantComms, serviceCharge);
//		}else{
//			LogUtil.Info("fail identity.type:"+identity.type);
//		}
//	}
//
//	//获取用户身份过程中取到的数据结构
//	private static class UserIdentity{
//		final int type; //0非粉丝 1粉丝 2团长
//		final Groupleader groupleader;
//		final Leaderfan leaderfan;
//		private UserIdentity(int type, Groupleader groupleader, Leaderfan leaderfan) {
//			this.type = type;
//			this.groupleader = groupleader;
//			this.leaderfan = leaderfan;
//		}
//	}
//	/**
//	 * 检测订单用户身份
//	 * @param userorder
//	 * @return
//	 */
//	private UserIdentity checkUserIdentity(Userorder userorder) {
//		Date beforeDate = userorder.getGmtCreated();
//		Long userId = userorder.getUserId();
//		//首先从groupleader获取
//		//只要这个人之前出现在groupLeader表，那他当时就是团长
//		Groupleader groupleader = groupleaderService.getByParamss(
//				mapWithOneEntry(Common.USERID ,userId),
//				null,null,null,
//				mapWithOneEntry(Common.GMTCREATED ,beforeDate)
//		);
//		if (groupleader != null ){
//			return new UserIdentity(2,groupleader,null);
//		}
//		//从userorder里的unioid判断他是否是粉丝
//		Leaderfan leaderfan = leaderfanService.getByParamss(
//				mapWithOneEntry("unionid",userorder.getUnioid()),
//				null,null,null,
//				mapWithOneEntry(Common.GMTCREATED,beforeDate)
//		);
//		if (leaderfan == null){ //可能不必要？
//			Userwechat userwechat = userwechatService.getByParam(mapWithOneEntryNoDel(Common.USERID,userId));
//			if (userwechat!=null){
//				leaderfan = leaderfanService.getByParamss(
//						mapWithOneEntry("unionid",userwechat.getUnionid()),
//						null,null,null,
//						mapWithOneEntry(Common.GMTCREATED,beforeDate)
//				);
//			}
//		}
//		if (leaderfan != null ){
//			return new UserIdentity(1,null,leaderfan);
//		}
//		return new UserIdentity(0,null,null);
//	}
//
//
//	/**
//	 * 团长佣金计算方法
//	 * @param userIdentity
//	 * @param orderprofitdetail
//	 * @param userorder
//	 * @param payAmount
//	 * @param merchantComms
//	 * @param serviceCharge
//	 */
//	private void getleaderComms(UserIdentity userIdentity,Orderprofitdetail orderprofitdetail,Userorder userorder,double payAmount,double merchantComms,double serviceCharge) {
//		Groupleader groupleader;
//		//自己不是团长
//		if (userIdentity.groupleader == null) {
//			LogUtil.Info("goupleader == null");
//			//如果已经是粉丝，不为空
//			Leaderfan leaderfan = userIdentity.leaderfan;
//			Long leaderId;
//			//如果通过链接进入，能取到userorder.leaderId
//			if (leaderfan == null) {
//				leaderId = userorder.getLeaderId();
//				LogUtil.Info("get userorder.leaderId");
//			} else {
//				leaderId = leaderfan.getLeaderId();
//				LogUtil.Info("get leaderfan.leaderId");
//			}
//			if (leaderId == null) {
//				LogUtil.Info("fail get leaderId (getleaderComms)");
//			}
//			//用leaderId获取groupleader（实际上只用来获取名字，和验证存在）
//			//不做noDel判断，因为leader和groupLeader是一对一的
//			groupleader = groupleaderService.getByParam(mapWithOneEntry(Common.ID, leaderId));
//			if (groupleader == null){
//				LogUtil.Info("fail fetch groupleader(leaderId):" + leaderId);
//				return;
//			}
//		}else{ //自己就是团长
//			LogUtil.Info("get groupleader by userId");
//			//从下单人直接获取groupLeader
//			//只有 orderid = 3038,3040，leaderstore的leaderId=26525,26526 的数据会出现多条，但多条的level都是一样的
//			groupleader=groupleaderService.getByParam(mapWithOneEntry(Common.USERID,userorder.getUserId()));
//			if (groupleader == null){
//				LogUtil.Info("fail fetch groupleader(userId):" + userorder.getUserId());
//				return;
//			}
//		}
//
//		//用leaderId获取leaderStore信息，店铺注册时间应该小于订单创建时间
//		List<Leaderstore> storeList = leaderstoreService.getByParamsList(
//				mapWithOneEntry("leaderId", groupleader.getId()),
//				null,
//				mapWithOneEntry(Common.ID,Common.DESC),
//				0,9999,null,
//				mapWithOneEntry("gmtReg",userorder.getGmtCreated())
//		);
//		//取第一个（最新的那个），或者取level=1的那一个（顶级团长）
//		Leaderstore leaderstore = null;
//		for(Leaderstore lf : storeList) {
//			if (lf.getLevel() == 1){
//				leaderstore = lf;
//				break;
//			}else if (leaderstore == null){
//				leaderstore = lf;
//			}
//		}
//		if (leaderstore == null){
//			LogUtil.Info("fail fetch leaderstore:" + groupleader.getId());
//			return;
//		}
//		if (leaderstore.getLevel()==1) { //团长等级(0普通用户 1顶级团长 2二级团长)
//			LogUtil.Info("leaderstore.getLevel()==1");
//			//订单为一级团长订单时
//			//计算团长佣金
//			//1.确定团长佣金比例
//			double topLeaderRate=setleaderlevelService.getLeaderRate(1)+setleaderlevelService.getLeaderRate(2);
//			//2.计算团长佣金
//			double leaderComms= ROUND_HALF_EVEN(payAmount*(topLeaderRate*0.01));
//			//3.计算平台佣金
//			double platComms=payAmount-merchantComms-leaderComms-serviceCharge; //应该不需要四舍六入
//			//添加分佣记录
//			orderprofitdetail.setType(0); //(0顶级团长分佣 1二级团长分佣 2平台分佣) 原为type，修改为0
//
//			orderprofitdetail.setLeaderId1(leaderstore.getLeaderId());
//			orderprofitdetail.setFirstUser(groupleader.getName());
//			orderprofitdetail.setFirstAmount(leaderComms);
//
//			orderprofitdetail.setPlatAmount(platComms);
//			orderprofitdetail.setMerchantId(userorder.getMerchantId());
//			orderprofitdetail.setMerAmount(merchantComms);
//			orderprofitdetail.setServiceCharge(serviceCharge);
//			orderprofitdetail.setGmtModify(new Date());
//			orderprofitdetailService.saveOrUpdate(orderprofitdetail);
//			LogUtil.Info("leaderstore.getLevel()==1 save");
//		}else if(leaderstore.getLevel()==2){
//			LogUtil.Info("leaderstore.getLevel()==2");
//			//当团长为二级团长时
//			//1.确定二级团长的佣金
//			double secondLeaderComms=ROUND_HALF_EVEN(payAmount*(setleaderlevelService.getLeaderRate(2)*0.01));
//			//2.确定一级团长佣金
//			double firstLeaderComms=ROUND_HALF_EVEN(payAmount*(setleaderlevelService.getLeaderRate(1)*0.01));
//			//3.计算一二级团长佣金的总和
//			double allLeaderComms=secondLeaderComms+firstLeaderComms;
//			//4.计算平台佣金
//			double platComms=payAmount-merchantComms-allLeaderComms-serviceCharge;
//
//			//6.添加一级团长佣金信息
//			//用storeId获取店铺的一级团长leaderStore信息
//			//取最接近当时时间点的一级团长(部分store有多个一级团长）
//			HashMap <String,Object> params=new HashMap<>();
//			params.put("storeId", leaderstore.getStoreId());
//			params.put("level", 1);
//			Leaderstore topLeaderstore=leaderstoreService.getByParamss(
//					params,
//					null,
//					mapWithOneEntry("gmtReg",Common.DESC),
//					null,
//					mapWithOneEntry("gmtReg",userorder.getGmtCreated())
//					);
//			if (topLeaderstore == null){
//				LogUtil.Info("fail fetch topLeaderstore:" + leaderstore.getStoreId());
//				return;
//			}
//
//			//获取一级团长的groupLeader信息
//			Groupleader firstGroupleader=groupleaderService.getByParam(
//					mapWithOneEntry(Common.ID,leaderstore.getLeaderId()));
//			if (firstGroupleader==null) {
//				LogUtil.Info("fail fetch firstGroupleader:" + leaderstore.getLeaderId());
//				return;
//			}
//			//添加分佣记录
//			orderprofitdetail.setType(1); //(0顶级团长分佣 1二级团长分佣 2平台分佣) 原为type，修改为1
//
//			orderprofitdetail.setLeaderId1(topLeaderstore.getLeaderId());
//			orderprofitdetail.setFirstUser(firstGroupleader.getName());
//			orderprofitdetail.setFirstAmount(firstLeaderComms);
//
//			orderprofitdetail.setLeaderId2(leaderstore.getLeaderId());
//			orderprofitdetail.setSecondUser(groupleader.getName());
//			orderprofitdetail.setSecondAmount(secondLeaderComms);
//
//			orderprofitdetail.setPlatAmount(platComms);
//			orderprofitdetail.setMerchantId(userorder.getMerchantId());
//			orderprofitdetail.setMerAmount(merchantComms);
//			orderprofitdetail.setServiceCharge(serviceCharge);
//
//			orderprofitdetail.setGmtModify(new Date());
//			orderprofitdetailService.saveOrUpdate(orderprofitdetail);
//			LogUtil.Info("leaderstore.getLevel()==2 save");
//		}else{
//			LogUtil.Info("fail leaderstore's level: " +leaderstore.getLevel() +"("+ leaderstore.getId() + ")" );
//		}
//	}

}
